package com.sandwormz.webcompiler;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.google.common.base.Preconditions;
import com.sandwormz.webcompiler.Page.TextElement;

/**
 * Represents the markup used in html files to designate areas containing
 * javascript to compile, use as externs, any included files to copy, and any
 * content to omit.
 * 
 * @author mbryant
 */
public class Annotation {

    public static class AnnotationBuilder {
        private String name = null;
        private int line = -1;
        private Map<String, String> options;

        @SuppressWarnings("synthetic-access")
        public Annotation build() {
            Preconditions.checkState(this.name != null, "name is required.");
            Preconditions.checkState(this.line > -1,
                    "a line number is required.");
            Annotation annotation = new Annotation(this.name);
            if (null != this.options) {
                annotation.setOptions(this.options);
                annotation.setLine(this.line);
            }
            return annotation;
        }

        public AnnotationBuilder line(final int line) {
            Preconditions
                    .checkState(line > -1, "line number must be positive.");
            this.line = line;
            return this;
        }

        public AnnotationBuilder name(final String name) {
            this.name = name;
            return this;
        }

        public AnnotationBuilder options(final Map<String, String> options) {
            this.options = options;
            return this;
        }
    }

    public static AnnotationBuilder Builder() {
        return new AnnotationBuilder();
    }

    private final AnnotationType type;

    private List<TextElement> containedElements = new LinkedList<TextElement>();

    private Map<String, String> options;

    private int line;

    private Annotation(final String name) {
        this.type = AnnotationType.valueOf(name);
    }

    /**
     * @param element
     */
    public void addTextElement(final TextElement element) {
        this.containedElements.add(element);
    }

    /**
     * @return
     */
    public List<TextElement> getContainedTextElements() {
        return this.containedElements;
    }

    public int getLine() {
        return this.line;
    }

    public String getName() {
        return this.type.toString();
    }

    /**
     * @param string
     * @return
     */
    public String getOption(final String key) {
        return this.options.get(key);
    }

    public AnnotationType getType() {
        return this.type;
    }

    public boolean hasOption(final String key) {
        return this.options.containsKey(key);
    }

    /**
     * @param string
     * @return
     */
    public boolean hasOptionSet(final String key) {
        String option = this.getOption(key);
        if (null == option) {
            return false;
        } else if (option.equalsIgnoreCase("false")) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * @param line
     */
    public void setLine(final int line) {
        this.line = line;
    }

    /**
     * @param options2
     */
    public void setOptions(final Map<String, String> options) {
        this.options = options;
    }

    @Override
    public String toString() {
        return this.type.toString();
    }
}